<?php
declare(strict_types=1);

namespace app\install\business;

use think\facade\Db;

class Install
{
    public function getDirs(): array
    {
        $dirs = [
            ['name' => 'app', 'desc' => '核心文件目录', 'permission' => '可读', 'read' => false, 'write' => false, 'check' => false],
            ['name' => 'config', 'desc' => '配置文件存放目录', 'permission' => '可读可写', 'read' => false, 'write' => false, 'check' => false],
            ['name' => 'extend', 'desc' => '扩展目录', 'permission' => '可读', 'read' => false, 'write' => false, 'check' => false],
            ['name' => 'public', 'desc' => '静态资源存放目录', 'permission' => '可读可写', 'read' => false, 'write' => false, 'check' => false],
            ['name' => 'route', 'desc' => '路由目录', 'permission' => '可读', 'read' => false, 'write' => false, 'check' => false],
            ['name' => 'vendor', 'desc' => '依赖库目录', 'permission' => '可读', 'read' => false, 'write' => false, 'check' => false],
            ['name' => 'runtime', 'desc' => '临时文件存放目录', 'permission' => '可读可写', 'read' => false, 'write' => false, 'check' => false],
            ['name' => 'view', 'desc' => '模板目录', 'permission' => '可读', 'read' => false, 'write' => false, 'check' => false],
        ];
        foreach ($dirs as $key => $dir) {
            $dirs[$key]['read']  = is_readable('../' . $dir['name']);
            $dirs[$key]['write'] = is_writeable('../' . $dir['name']);

            $dirs[$key]['check'] = $dirs[$key]['read'] || $dirs[$key]['write'];
            if (in_array($dir['name'], ['config', 'public', 'runtime'])) {
                $dirs[$key]['check'] = $dirs[$key]['read'] && $dirs[$key]['write'];
            }
        }

        return $dirs;
    }

    public function checkDirs(array $dirs): bool
    {
        foreach ($dirs as $dir) {
            if (!$dir['check']) {
                return false;
            }
        }
        return true;
    }

    public function getExtensions(): array
    {
        $extensions = [
            ['name' => 'mbstring', 'desc' => '字符串处理', 'check' => false],
            ['name' => 'mysqli', 'desc' => '数据库链接', 'check' => false],
            ['name' => 'zip', 'desc' => '文件压缩扩展', 'check' => false],
            ['name' => 'iconv', 'desc' => '图标扩展', 'check' => false],
            ['name' => 'gd', 'desc' => '图形扩展', 'check' => false],
        ];
        foreach ($extensions as $key => $extension) {
            $extensions[$key]['check'] = extension_loaded($extension['name']);
        }
        return $extensions;
    }

    public function checkExtensions(array $extensions): bool
    {
        foreach ($extensions as $extension) {
            if (!$extension['check']) {
                return false;
            }
        }
        return true;
    }

    public function checkDb(array $data): array
    {
        $conn = @mysqli_connect($data['dbHost'], $data['dbUser'], $data['dbPass']);
        if (!$conn) {
            return ['result' => false, 'message' => '请检查数据库连接信息'];
        }

        $sql    = 'SHOW DATABASES LIKE \'' . $data['dbName'] . '\'';
        $result = @mysqli_query($conn, $sql);
        if ($result->num_rows) {
            return ['result' => false, 'message' => '数据库已经存在'];
        }
        return ['result' => true, 'message' => 'success'];
    }

    public function install(array $data): bool
    {
        $dbRes     = $this->_executeSql($data);
        $configRes = $this->_saveConfig($data);
        return $dbRes && $configRes;
    }

    public function checkInstalled(): bool
    {
        $completedTables = ['menu', 'merchant', 'role', 'role_menu_relation', 'merchant_role_relation', 'website', 'enterprise'];
        $installedTables = [];
        try {
            $installFlag = true;
            $tables      = Db::query('show tables');
            foreach ($tables as $table) {
                $installedTables = array_merge($installedTables, array_values($table));
            }
            if (count($tables) != count($completedTables)) {
                $installFlag = false;
            }
        } catch (\Exception $e) {
            $installFlag = false;
        }

        if (!$installFlag) {
            return false;
        }

        foreach ($completedTables as $completedTable) {
            if (!in_array($completedTable, $installedTables)) {
                $installFlag = false;
                break;
            }
        }

        return $installFlag;
    }

    private function _saveConfig(array $data): bool
    {
        $envContent = <<<str
APP_DEBUG=false

[cache]
DRIVER=file

[database]
DB_TYPE=mysql
DB_HOST={$data['dbHost']}
DB_NAME={$data['dbName']}
DB_USER={$data['dbUser']}
DB_PASS={$data['dbPass']}
DB_PORT={$data['dbPort']}
DB_CHARSET=utf8
str;
        file_put_contents('../.env', $envContent);
        file_put_contents('../install.lock', '');
        return true;
    }

    private function _executeSql(array $data): bool
    {

        $conn = @mysqli_connect($data['dbHost'], $data['dbUser'], $data['dbPass']);
        if (!$conn) {
            return false;
        }

        mysqli_query($conn, "CREATE DATABASE IF NOT EXISTS `" . $data['dbName'] . "` default charset utf8mb4;");
        mysqli_select_db($conn, $data['dbName']);
        mysqli_query($conn, "set names utf8");
        $sql = file_get_contents('../app/install/sql/tp.sql');
        if (!$sql) {
            return false;
        }

        try {
            $sqlArr = preg_split('/;/', $sql);
            foreach ($sqlArr as $v) {
                $temp = [];
                $preg = "/(\/\*.*\*\/)/isU";
                preg_match_all($preg, trim($v), $temp);
                $v = str_replace($temp[1], '', $v);
                if (!$v) {
                    continue;
                }

                mysqli_query($conn, $v);
            }
        } catch (\Exception $e) {
        }

        $pass     = md5($data['password']);
        $now      = date('Y-m-d H:i:s');
        $adminSql = <<<str
INSERT INTO `merchant` (`id`,`username`, `cellphone`, `email`, `password`, `status`, `enterprise_id`, `is_delete`, `created_at`, `updated_at`) VALUES (1, '{$data['username']}', '{$data['phone']}', '{$data['email']}', '$pass', 1, 0, 1, '$now', '$now');
str;
        mysqli_query($conn, $adminSql);

        $roleSql = <<<str
INSERT INTO `merchant_role_relation` (`id`, `merchant_id`, `role_id`, `is_delete`, `created_at`, `updated_at`) VALUES (23, 1, 1, 1, '2023-08-15 14:43:04', '2023-08-15 14:43:04');
str;
        mysqli_query($conn, $roleSql);

        mysqli_close($conn);

        return true;
    }
}
